home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
EnigmA Amiga Run 1999 March
/
EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso
/
earcd
/
devel
/
vbcc-wos
/
doc
/
vbcc.doc
< prev
next >
Wrap
Text File
|
1999-01-01
|
26KB
|
660 lines
vbcc - C compiler (c) in 1995-99 by Volker Barthelmann
vbpp - C preprocessor (c) in 1995-96 by Thorsten Schaaps
INTRODUCTION
vbcc is a free portable and retargetable ANSI C compiler.
It is split into a target-independant and a target-dependant part, and
supports emulating datatypes of the target machine on any other machine
so that it is possible to e.g. make a crosscompiler for a 64bit machine
on a 32bit machine.
The target-independant part generates a form of intermediate code
(quads) which has to be dealt with by the code generator. This
intermediate code is rather cpu independant (apart from register usage)
but the target-independant part of vbcc uses informations about the
target machine while generating this code.
If you are interested in writing a code generator for vbcc, contact
me (the necessary documents are not written yet).
This document only deals with the target-independant parts of vbcc.
Be sure to read all the documents for your machine.
LEGAL
vbcc is (c) in 1995-99 by Volker Barthelmann. The builtin preprocessor
(consisting of the files preproc.c and vbpp.h) is written and (c) by
Thorsten Schaaps. All other code is (c) by Volker Barthelmann.
vbcc may be freely redistributed as long as no modifications are made
and nothing is charged for it.
Non-commercial usage of vbcc is allowed without any restrictions.
Commercial usage needs my written consent.
Sending me money, gifts, postcards etc. would be very nice and may
encourage further development of vbcc, but is not legally or morally
necessary to use vbcc.
INSTALLATION
The installation is system dependant and covered in another manual.
USAGE
Usually vbcc will be called by a frontend. However, if you call it
directly it has to be done like this (and most of the options
should be passed through to vbcc by the frontend):
vbcc [options] file
The following options are supported by the machine independant part
of vbcc:
-quiet Do not print the copyright notice.
-ic1 Write the intermediate code before optimizing to file.ic1.
-ic2 Write the intermediate code after optimizing to file.ic2.
-debug=n Set the debug level to n.
-o=ofile Write the generated assembler output to <ofile> rather than
the default file.
-noasm Do not generate assembler output (only for testing).
-O=n Turns optimizing options on/off; every bit set in n turns
on an option.
(See section on optimizing.)
-maxoptpasses=n
Set maximum number of optimizer passes to n.
(See section on optimizing.)
-inline-size=n
Set the maximum 'size' of functions to be inlined.
(See section on optimizing.)
-unroll-size=n
Set the maximum 'size' of unrolled loops.
(See section on optimizing.)
-fp-associative
Floating point operations do not obey the law of
associativity, e.g. (a+b)+c==a+(b+c) is not true for all
floating point numbers a,b,c. Therefore certain optimizations
depending on this property cannot be performed on floating
point numbers.
With this option you can tell vbcc to treat floating point
operations as associative and perform those optimizations
even if that may change the results in some cases (not
ANSI conforming).
-no-alias-opt
If the optimizer is turned on, vbcc has to make assumptions
on aliasing (i.e. which pointer can point to which
objects at a given time). If this option is specified,
vbcc will make worst-case assumptions and some
non-conforming programs could be made to work that way.
-no-multiple-ccs
If the code generator supports multiple condition code
registers, vbcc will try to use them when optimizing.
This flag prevents vbcc from using them.
-iso
-ansi Switch to ANSI/ISO mode.
In ANSI mode warning 209 will be printed by default.
'__reg' and inline-assembly-functions are not recognized.
Also assignments between pointers to <type> and pointers
to unsigned <type> will cause warnings.
-maxerrors=n
Abort the compilation after n errors; do not stop if n==0.
-dontwarn=n
Suppress warning number n; suppress all warnings if n<0.
(See the section on errors/warnings.)
-warn=n
Turn on warning number n; turn on all warnings if n<0.
(See the section on errors/warnings.)
-strip-path
Strip the path of filenames in error messages.
Error messages may look more convenient to some people that
way, but using this together with message browsers or
similar programs could cause trouble.
-nested-comments
Allow nested comments (not ANSI conforming).
Has no effect if the builtin preprocessor is disabled.
-cpp-comments
Allow C++ style comments (not ANSI conforming).
Has no effect if the builtin preprocessor is disabled.
-macro-redefinition
Allow redefinition of macros (not ANSI conforming).
Has no effect if the builtin preprocessor is disabled.
-no-trigraphs
Prevents expansion of trigraphs (not ANSI conforming).
Has no effect if the builtin preprocessor is disabled.
-no-preprocessor
Do not invoke the builtin preprocessor vbpp.
-E Only preprocess the file and write the preprocessed
source to <file>.i.
-dontkeep-initialized-data
By default vbcc keeps all data of initializations in memory
during the whole compilation (it can sometimes make use
of this when optimizing). This can take some amount of
memory, though. If this option is specified, vbcc does not
keep this data in memory and uses less memory.
This has not yet been tested very well.
The assembler output will be saved to file.asm (if file already contained
a suffix, this will first be removed; same applies to .ic1/.ic2)
SOME INTERNALS
I try to make vbcc as ANSI compliant as possible, so I am only mentioning
some things I consider interesting.
ERRORS/WARNINGS
vbcc knows the following kinds of messages:
fatal errors Something is badly wrong and further compilation is
impossible or pointless. vbcc will abort.
E.g. no source file or really corrupt source.
errors There was an error and vbcc cannot generate useful
code. Compilation continues, but no code will be
generated.
E.g. unknown identifiers.
warnings (1) Warnings with ANSI-violations. The program is not
ANSI-conforming, but vbcc will generate code that
could be what you want (or not).
E.g. missing semicolon.
warnings (2) The code has no ANSI-violations, but contains some
strange things you should perhaps look at.
E.g. unused variables.
Errors or the first kind of warnings are always displayed and cannot
be suppressed.
Only some warnings of the second kind are turned on by default.
Many of them are very useful for some but annoying to others, and
their usability may depend on programming style. As I do not want
to force anyone to a certain style, I recommend everyone to find
their own preferences.
A good way to do this is starting with all warnings turned on by
-warn=-1. So you will see all possible warnings. Now everytime you
get a warning you do not find useful, turn that one off with
-dontwarn=n.
The file errors.doc contains a list of all errors/warnings, sometimes
with more detailed descriptions. This might be very useful, too.
See the docs on your frontend on how to configure it to your
preferences.
DATA TYPES
vbcc can handle the following atomic data types:
signed/unsigned char/short/int/long (signed is always default)
float/double (long double is always the same as double)
However several of them can be identical in certain implementations.
OPTIMIZATIONS
vbcc can compile with or without global optimizations.
But note that the optimizer is not yet finished and has not been
tested much. So only use it with care.
In the first compilation phase every function is parsed into a tree
structure one expression after the other. Then type-checking and some
minor optimizations like constant-folding or some algebraic
simplifications are done on the trees.
This phase of the translation is identical in optimizing and
non-optimizing compilation.
Then intermediate code is generated from the trees. In non-optimizing
compilation temporaries needed to evaluate the expression are
immediately assigned to registers, if possible. In optimizing
compilation, a new variable is generated for each temporary required.
Also for certain constructs like loops, different intermediate code
is produced in optimizing compilation.
Some minor optimizations are performed while generating the intermediate
code (simple elimination of unreachable code, some optimizations on
branches etc.).
After intermediate code for the whole function has been generated
simple register allocation may be done in non-optimizing compilation
if bit 1 has been set in the -O option.
After that, the intermediate code is passed to the code generator and
then all memory for the function, its variables etc. is freed.
In optimizing compilation flowgraphs are constructed, data flow analysis
is performed and many passes are made over the function's intermediate
code. Code may be moved around, new variables may be added, other
variables removed etc. etc. (for more detailed information on the
performed optimizations look at the description for the -O option
below).
Many of the optimization routines depend on each other and if one
routine finds an optimization, this often enables other routines to
find further ones. Also some routines only do a first step and let
other routines 'clean up' afterwards. Because of this, vbcc usually
makes many passes until no further optimizations are found.
To avoid possible extremely long optimization times, the number of
those passes can be limited with the -maxoptpasses=n option (the
default value is max. 10 passes).
Now it will be decided if the compiled function is a candidate for
inlining. In this case the intermediate code, as well as the data
structures for the local variables, will be copied and stored until
compilation of the entire translation-unit has finished.
After those phases, register allocation should be done. As temporaries
have not been assigned to registers up to this point, register
allocation is crucial in optimizing compilation (note that some flags
MUST be turned on).
Note that optimizing compilation can take MUCH more time and needs
MUCH more memory. It is hard to predict how much time and space it
needs, but usually it roughly depends on length of a function (time
and space needed will usually increase more than linear with the
length of a function).
At the moment the following bits in the -O option are recognized:
Bit 0 (1) Register allocation
This is the only flag that has any effect in non-optimizing compilation.
In non-optimizing compilation, any registers that have never been used
for temporaries in this function are used for register variables in a
simple way.
For each variable, a priority to registerize it is computed (this has
already been done during generation of intermediate code). This value
usually reflects how much can be gained by putting it in a register.
Then, for every free register, the variable with the highest priority
that can be stored in that register is assigned that register for
the entire function.
This improves the generated code quite a bit.
In optimizing compilation several passes are made:
- First, all temporaries are assigned to registers in basic blocks.
Temporaries are recognized by utilising data flow information on
active variables, and one variable can be a temporary at one or
several points although it is alive over several basic blocks at
another point.
- Then vbcc computes approximate savings that can be obtained by
holding a variable in a register within a certain program region
(usually a loop) and assigns the most used variables to registers
within this region.
Information on the function's loop structure and active variables
are used.
Bit 1 (2) activate optimizing compilation
This flag turns on the optimizer. If it is set to zero, no global
optimizations will be performed, no matter what the other flags are set
to.
When turned on, slightly different intermediate code will be generated
by the first translation phases.
Also the following optimizations are performed:
- A flow graph is constructed and unused labels are deleted.
- Unreachable code is eliminated.
- Jump optimizations are performed.
- Several peephole optimizations, like constant folding and algebraic
simplifications, are performed on the intermediate code.
- Identical statements at the beginning/end of basic blocks are
moved to the successors/predecessors under certain conditions.
Bit 2 (4) common subexpression elimination
The intermediate code is scanned for common subexpressions that can be
eliminated. Also copy propagation is performed.
This can be done only within basic blocks or over the whole function,
depending on bit 5.
If global cse is selected, data flow analysis for available expressions
and available copies is performed.
Note that the local versions of these optimizations are only restricted
versions of the global ones. They operate on the intermediate code
rather than on trees and therefore are slower than they could be
on compilers that only perform local versions.
Bit 3 (8) constant propagation
Variables which are known to have a constant value at one time are
replaced by constants.
This can be done only within basic blocks or over the whole function,
depending on bit 5.
If global constant propagation is selected, data flow analysis for
reaching definitions is performed.
Note that the local versions of these optimizations are only restricted
versions of the global ones. They operate on the intermediate code
rather than on trees and therefore are slower than they could be
on compilers that only perform local versions.
Bit 4 (16) elimination of dead code
Code which computes a value that is never used will be eliminated.
Lots of dead code may be generated during the process of optimizing,
so this optimizations is crucial.
Bit 5 (32) global optimization
Some optimizations are available in local and global versions. This
flag turns on the global versions.
At the moment, this effects common subexpression elimination, copy
propagation, constant propagation and loop optimizations.
Also, if this flag is not turned on, only one optimization pass is
done, whereas several are done if it is turned on.
Not turning on this flag results in worse code and often shorter
compile time. However, there are cases where this increases compile
time.
Bit 6 (64) reserved for future use
Bit 7 (128) loop optimizations
vbcc will try to identify loops and perform the following optimizations
on the loops it finds:
- frequency-reduction: Loop-invariant operations will be moved out of
the loop.
- strength-reduction: Linear functions of induction variables will be
replaced by additional induction variables.
These only work in conjunction with bit 5 (32).
Bit 8 (256) merge variable space
vbcc tries to place variables at the same memory addresses if possible.
Bit 9 (512) reserved for future use
Bit 10 (1024) move assignments out of loops
If bits 5, 7 and 10 are set, vbcc will try to move loop-invariant
assignments out of loops.
Bit 11 (2048) loop-unrolling
vbcc tries to unroll certain loops. Only works together with bit 5 (32)
and bit 7 (128). At the moment a loop is only unrolled if the number
of iterations can be determined at compile time. In the future, loops
may also be unrolled if the number of iterations can be calculated at
loop entry.
With -unroll-size you can specify how many intermediate instructions
the unrolled loop should have at most.
Bit 12 (4096) function inlining
The intermediate code of functions that meet certain conditions
(mainly adjustable by -inline-size) is kept in memory for the entire
translation unit, and subsequent calls to this function are replaced
with this code.
This way, constant arguments can be propagated across the function
and certain parts of the function may be omitted. Also common
subexpressions across the functions can be eliminated.
An inlined function call is about the same as a macro expansion (but
safer).
Also look at #pragma only-inline in the following section.
Also look at the documentation for the target-dependant part of vbcc.
There may be additional machine specific optimization options.
EXTENSIONS
#pragma:
At the moment vbcc accepts the following #pragma-directives:
#pragma printflike <function> This tells vbcc to handle <function>
#pragma scanflike <function> specially.
<function> must be an already declared
function, with external linkage, that
takes a variable number of arguments
and a const char * as the last fixed
parameter.
If such a function is called with a
string-constant as format-string, vbcc
will check if the arguments seem to
match the format-specifiers in the
format-string, according to the rules
of printf or scanf.
Also, vbcc will replace the call by a
call to a simplified version according
to the following rules, if such a
function has been declared with external
linkage:
If no format-specifiers are used at all,
__v0<function> will be called.
If no qualifiers are used and only
d,i,x,X,o,s,c are used, __v1<function>
will be called.
If no floating-point arguments are used,
__v2<function> will be called.
#pragma only-inline on The following functions are prepared for
inlining, but no code is generated. This
can be used e.g. in header-files to
supply inline versions of certain
functions.
-inline-size is ignored in this mode -
every function gets prepared for
inlining.
Do not use this with functions that have
local static variables!
#pragma only-inline off The following functions are translated
as usual again.
#pragma opt <n> Sets the optimization options to <n>
(similar to -O=<n>) for the following
functions.
Never use this inside a function!
#pragma type <expr> Write the type of <expr> to stdout.
This is mainly intended for testing.
#pragma tree <expr> Write the parse-tree of <expr> to stdout.
This is mainly intended for testing.
Register parameters:
If the parameters for certain functions should be passed in certain
registers, you can specify the registers with __reg("<reg>") in the
prototype, e.g.
void f(__reg("d0") int x, __reg("a0") char *y) { ... }
The names of the available registers depend on the code generator.
Note that a matching prototype must be in scope when calling such
a function - or wrong code will be generated.
Therefore it is not useful to use register parameters in an old-style
function-definition.
If the code generator cannot handle the specified register for a
certain type, this will cause an error. Note that this may happen
although the register could store that type, if the code generator
does not know about it.
Also note that this may force vbcc to create worse code.
__reg is not recognized when ANSI/ISO mode is turned on.
Inline-assembly-functions:
Only use them if you know what you are doing!
A function-declaration may be followed by '=' and a string-constant.
If a function is called with such a declaration in scope, then no
function-call will be generated but the string-constant will be
inserted in the assembly-output.
Otherwise the compiler and optimizer will treat this like a
function-call, i.e. the inline-assembly must not modify any callee-save
registers without restoring them. (In the future there will be
possibilities to specify side-effects of function-calls to prevent the
compiler from having to use worst-case-assumptions.)
Example:
double sin(__reg("fp0") double) = "\tfsin.x\tfp0\n";
Inline-assembly-functions are not recognized when ANSI/ISO mode is
turned on.
Target-specific variable attributes
Some targets may offer additional options which are syntactically
similar to storage-class-specifiers. Multiple specification of an
attribute or redeclaration of a variable with a differing setting of
an attribute will cause a warning.
However, no further checkings will be applied. E.g. if an attribute
is given to a variable it is not applicable to they will usually be
silently ignored.
Further details may be found in the target-specific documentation.
Target-specific variable attributes are not recognized when ANSI/ISO
mode is turned on.
__typeof:
__typeof is syntactically equivalent to sizeof, but its result is of
type int and is a number representing the type of its argument.
This may be necessary for implementing stdarg.h.
KNOWN PROBLEMS
Some known target-independant problems of vbcc at the moment:
- Some size limits are still hardcoded into the program (the maximum
nesting of blocks and the maximum length of input lines).
- Bitfields are not really supported (they are always used as int).
- 'volatile' is sometimes ignored.
- long double is not really supported (see errors.doc).
- The optimizer is not finished and may have a few bugs.
CREDITS
All those who wrote parts of the vbcc distribution, made suggestions,
answered my questions, tested vbcc, reported errors or were otherwise
involved in the development of vbcc (in descending alphabetical order,
under work, not complete):
Frank Wille
Gary Watson
Johnny Tevessen
Ralph Schmidt
Markus Schmidinger
Thorsten Schaaps
Anton Rolls
Michaela Pruess
Joerg Plate
Gilles Pirio
Bartlomiej Pater
Gunther Nikl
Robert Claus Mueller
Joern Maass
Aki M Laukkanen
Kai Kohlmorgen
Uwe Klinger
Andreas Kleinert
Julian Kinraid
Acereda Macia Jorge
Dirk Holtwick
Kasper Graversen
Jens Granseuer
Volker Graf
Marcus Geelnard
Matthias Fleischer
Alexander Fichtner
Olivier Fabre
Robert Ennals
Thomas Dorn
Walter Doerwald
Aaron Digulla
Lars Dannenberg
Sam Crow
Michael Bode
Michael Bauer
Juergen Barthelmann
Thomas Arnhold
Alkinoos Alexandros Argiropoulos
Thomas Aglassinger
Volker Barthelmann volker@vb.franken.de